package com.ruoyi.word.service.impl;

import com.ruoyi.common.constant.RedisEnum;
import com.ruoyi.common.core.redis.CommonRedisService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.domain.word.*;
import com.ruoyi.common.domain.word.vo.*;
import com.ruoyi.word.dao.mapper.*;
import com.ruoyi.word.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class CommonWordServiceImpl implements ICommonWordService {

    @Autowired
    private CommonWordMapper dao;
    @Autowired
    private ICommonWordRaService raService;
    @Autowired
    private ICommonWordPhraseService phraseService;
    @Autowired
    private ICommonWordSimpleSentenceService simpleSentenceService;
    @Autowired
    private ICommonWordFormService formService;
    @Autowired
    private ICommonWordPronounceService pronounceService;
    @Autowired
    private CommonRedisService redisService;

//    @Autowired
//    private CommonWordEsServiceImpl wordEsService;

    @Override
    public int saveOrUpdate(CommonWord word) {
        return dao.insertSelective(word);
    }

    @Override
    public List<CommonWord> findByWhereStr(String whereStr, String orderField, String order) {
        return dao.findByWhereStr(whereStr, orderField, order);
    }

    @Override
    public CommonWord findByWord(String word) {
        CommonWord record = dao.findByWord(word);
        if(record != null) {
            record.setPronounceList(pronounceService.findByWid(record.getId()));
        }
        return record;
    }

    @Override
    public CommonWord findById(Long id) {
        CommonWord word =  dao.selectByPrimaryKey(id);
        if(word == null) {
            return null;
        }
        // word.setRaList(raService.findByWid(id));
        // word.setPhraseList(phraseService.findByWid(id));
        // word.setSimpleSentenceList(simpleSentenceService.findByWid(id));
        return word;
    }

    @Override
    public CommonWord findWordByWid(Long wid) {
        String key = RedisEnum.WORD_WITH_PRONOUNCE_.getKey() + wid;
        Optional<CommonWord> op = redisService.getAsOptional(key);
        if (op.isPresent()){
            return op.get();
        }
        CommonWord commonWord = dao.selectByPrimaryKey(wid);
        List<CommonWordPronounce> pronounceList = pronounceService.findByWid(wid);
        if (pronounceList.size() != 0){
            commonWord.setPronounceList(pronounceList);
        }
        redisService.put(key, commonWord, RedisEnum.WORD_WITH_PRONOUNCE_.getExpire());
        return commonWord;
    }

    @Override
    public int save(CommonWord record) {
        Date date = new Date();
        record.setAddTime(date);
        record.setUpdateTime(date);
        int result = dao.insertSelective(record);
        if(result > 0){
            rebuildAttr(record);
            // 清缓存
            cleanRedis(record.getId());
            // 更新至es
            // wordEsService.saveOrUpdate(findByIdVo(record.getId()));
        }
        return result;
    }

    @Override
    public int update(CommonWord record) {
        record.setUpdateTime(new Date());
        int result = dao.updateByPrimaryKeySelective(record);
        if(result > 0){
            rebuildAttr(record);
            // 清缓存
            cleanRedis(record.getId());
            // 更新至es
            // wordEsService.saveOrUpdate(findByIdVo(record.getId()));
        }
        return result;
    }

    private void cleanRedis(Long wid){
        // 单词详情
        redisService.remove(RedisEnum.WORD_DETAILS_VOC_.getKey() + wid);
        redisService.remove(RedisEnum.WORD_WITH_PRONOUNCE_.getKey() + wid);
    }

    private void rebuildAttr(CommonWord record) {
        raService.saveByWord(record, buildWordRa(record));
        phraseService.saveByWord(record, buildWordPhrase(record));
        simpleSentenceService.saveByWord(record, buildWordSimpleSentence(record));
        formService.saveByWord(record, buildWordFrom(record));
        pronounceService.saveByWord(record, buildWordPronounce(record));
    }

    @Override
    public int updateByPrimaryKeySelective(CommonWord record) {
        return dao.updateByPrimaryKeySelective(record);
    }

    @Override
    public int delete(Long id) {
        int result = dao.deleteByPrimaryKey(id);
        if(result > 0) {
            raService.deleteByWid(id);
            phraseService.deleteByWid(id);
            simpleSentenceService.deleteByWid(id);
            formService.deleteByWid(id);
            pronounceService.deleteByWid(id);
            // 清缓存
            cleanRedis(id);
            // 更新至es
            // wordEsService.delete(id);
        }
        return result;
    }

    @Override
    public List<CommonWordVocabularyVo> findByWhereStrWord(String whereStr, String orderField, String order, Long vocabularyId) {
        //通过这个单词本的id 去关联item表和word表，对于返回的 已经存在于item表的数据在idAdd字段做个标记
        return dao.findByWhereStrWord( whereStr, orderField, order, vocabularyId);
    }

    @Override
    public List<CommonWordSysVocabularyVo> findByWhereStrWithId(String whereStr, String orderField, String order) {
        return dao.findByWhereStrWithId(whereStr, orderField, order);
    }

    @Override
    public List<CommonWord> findByWhereStrWithUserVocId(String whereStr, String orderField, String order) {
        return dao.findByWhereStrWithUserVocId(whereStr, orderField, order);
    }

    @Override
    public List<CommonWord> findFiveAndFiveWords() {
        return dao.findFiveAndFiveWords();
    }

    @Override
    public List<CommonWord> findBySysId(Long sysId) {
        return dao.findBySysId(sysId);
    }

    @Override
    public CommonWordVo findByIdVo(Long id) {
        return dao.findByIdVo(id);
    }

    private List<CommonWordRa> buildWordRa(CommonWord word){
        if(word == null || word.getId() == null) {
            return new ArrayList<>();
        }
        if(word.getRaList() != null) {
            return word.getRaList();
        }
        List<CommonWordRa> list = new ArrayList<>();
        // 前缀
        getWordRa(word.getPrefix(), list, CommonWordRa.TYPE_PREFIX);
        // 词根
        getWordRa(word.getStem(), list, CommonWordRa.TYPE_STEM);
        // 后缀
        getWordRa(word.getSuffix(), list, CommonWordRa.TYPE_SUFFIX);
        return list;
    }

    private List<CommonWordPhrase> buildWordPhrase(CommonWord word) {
        if(word == null || word.getId() == null) {
            return new ArrayList<>();
        }
        if(CollectionUtils.isEmpty(word.getPhraseList())) {
            return new ArrayList<>();
        }
        Date date = new Date();
        int index = 1;
        List<CommonWordPhrase> result = new ArrayList<>();
        for (CommonWordPhrase phrase: word.getPhraseList()) {
            if(StringUtils.isEmpty(phrase.getContent())) {
                continue;
            }
            phrase.setAddTime(date);
            phrase.setWid(word.getId());
            phrase.setSort(index++);
            result.add(phrase);
        }
        return result;
    }

    private List<CommonWordSimpleSentence> buildWordSimpleSentence(CommonWord word) {
        if(word == null || word.getId() == null) {
            return new ArrayList<>();
        }
        if(CollectionUtils.isEmpty(word.getSimpleSentenceList())) {
            return new ArrayList<>();
        }
        Date date = new Date();
        int index = 1;
        List<CommonWordSimpleSentence> result = new ArrayList<>();
        for (CommonWordSimpleSentence r: word.getSimpleSentenceList()) {
            if(StringUtils.isEmpty(r.getContent())) {
                continue;
            }
            r.setAddTime(date);
            r.setWid(word.getId());
            r.setSort(index++);
            result.add(r);
        }
        return result;
    }

    private List<CommonWordForm> buildWordFrom(CommonWord word) {
        if(word == null || word.getId() == null) {
            return new ArrayList<>();
        }
        if(CollectionUtils.isEmpty(word.getFormList())) {
            return new ArrayList<>();
        }
        Date date = new Date();
        int index = 1;
        List<CommonWordForm> result = new ArrayList<>();
        for (CommonWordForm wf: word.getFormList()) {
            if(StringUtils.isEmpty(wf.getName()) || StringUtils.isEmpty(wf.getValue())) {
                continue;
            }
            wf.setAddTime(date);
            wf.setWid(word.getId());
            wf.setWord(word.getName());
            wf.setSort(index++);
            result.add(wf);
        }
        return result;
    }

    private List<CommonWordPronounce> buildWordPronounce(CommonWord word) {
        if(word == null || word.getId() == null) {
            return new ArrayList<>();
        }
        if(CollectionUtils.isEmpty(word.getPronounceList())) {
            return new ArrayList<>();
        }
        Date date = new Date();
        List<CommonWordPronounce> result = new ArrayList<>();
        for (CommonWordPronounce pronounce: word.getPronounceList()) {
            if(StringUtils.isEmpty(pronounce.getContent())) {
                continue;
            }
            pronounce.setAddTime(date);
            pronounce.setWid(word.getId());
            result.add(pronounce);
        }
        return result;
    }

    private void getWordRa(String str, List<CommonWordRa> list, Integer type){
        if(StringUtils.isEmpty(str)) {
            return;
        }
        String r[] = str.split("\n");
        for (String rs: r) {
            if(StringUtils.isNotEmpty(rs)) {
                rs = rs.trim();
                int idx = rs.indexOf(" ");
                if(idx == -1) {
                    continue;
                }
                CommonWordRa ra = new CommonWordRa();
                ra.setName(rs.substring(0, idx).trim());
                ra.setPh(rs.substring(idx).trim());
                ra.setType(type);
                list.add(ra);
            }
        }
    }

    @Override
    public List<CommonWord> findByWrongPronounce() {
        return dao.findByWrongPronounce();
    }
}
